/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 主城模块
	/// module : mainCity
	/// </summary>
	public interface CNetMainCity : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction notifyWeather_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyWeatherData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mainCity_notifyWeather, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyWeather(session, _wrapper.message.weatherCid);
                MessageWrapperPool<NotifyWeatherData>.Put(_wrapper);
            };
            MessageFunction requestExeServiceResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<RequestExeServiceResultData>)wrapper;
                SC_requestExeServiceResult(session, ref _wrapper.message);
                MessageWrapperPool<RequestExeServiceResultData>.Put(_wrapper);
            };
            MessageFunction notifyNpcUpdate_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyNpcUpdateData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mainCity_notifyNpcUpdate, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyNpcUpdate(session, _wrapper.message.regionCid, _wrapper.message.npcData);
                MessageWrapperPool<NotifyNpcUpdateData>.Put(_wrapper);
            };
            MessageFunction notifyNpcDrop_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyNpcDropData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mainCity_notifyNpcDrop, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyNpcDrop(session, _wrapper.message.regionCid, _wrapper.message.npcId, _wrapper.message.awards);
                MessageWrapperPool<NotifyNpcDropData>.Put(_wrapper);
            };
            MessageFunction notifyNpcExecution_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyNpcExecutionData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mainCity_notifyNpcExecution, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyNpcExecution(session, _wrapper.message.regionCid, _wrapper.message.npcId, _wrapper.message.excutionId);
                MessageWrapperPool<NotifyNpcExecutionData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.mainCity_notifyWeather, (session, package) => {
                	var result = MessageWrapperPool<NotifyWeatherData>.Get();
                	result.Init(session, notifyWeather_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mainCity_requestExeServiceResult, (session, package) => {
                	var result = MessageWrapperPool<RequestExeServiceResultData>.Get();
                	result.Init(session, requestExeServiceResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mainCity_notifyNpcUpdate, (session, package) => {
                	var result = MessageWrapperPool<NotifyNpcUpdateData>.Get();
                	result.Init(session, notifyNpcUpdate_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mainCity_notifyNpcDrop, (session, package) => {
                	var result = MessageWrapperPool<NotifyNpcDropData>.Get();
                	result.Init(session, notifyNpcDrop_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mainCity_notifyNpcExecution, (session, package) => {
                	var result = MessageWrapperPool<NotifyNpcExecutionData>.Get();
                	result.Init(session, notifyNpcExecution_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        ///  通知天气更新
        /// </summary>
		protected void SC_notifyWeather(ISession session, int weatherCid);
		/// <summary>
        ///  执行服务结果
        /// </summary>
		public void SC_requestExeServiceResult(ISession session, ref RequestExeServiceResultData message) 
		{
            _SC_requestExeServiceResult(session, ref message);
		}
		
		public void _SC_requestExeServiceResult(ISession session, ref RequestExeServiceResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mainCity_requestExeServiceResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mainCity_requestExeServiceResult, message.code);
			MsgAsyncAwaiter<RequestExeServiceResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  通知npc更新
        /// </summary>
		protected void SC_notifyNpcUpdate(ISession session, int regionCid, MainCityNpcPOD npcData);
		/// <summary>
        ///  通知npc掉落
        /// </summary>
		protected void SC_notifyNpcDrop(ISession session, int regionCid, int npcId, List<ItemShowPOD> awards);
		/// <summary>
        ///  通知执行
        /// </summary>
		protected void SC_notifyNpcExecution(ISession session, int regionCid, int npcId, int excutionId);
#endregion
#region Server-side Interface
		/// <summary>
        /// 同步玩家坐标
        /// </summary>
    	public bool CS_uploadPlayerPos(int regionCid, float x, float y, float z) 
    	{
    		return _CS_uploadPlayerPos(regionCid, x, y, z);
    	}
    	public bool _CS_uploadPlayerPos(int regionCid, float x, float y, float z)
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mainCity_uploadPlayerPos, "Send->"+"MainCity.CS_uploadPlayerPos { "
				+ "regionCid="
				+ regionCid
				+ ", x="
				+ x
				+ ", y="
				+ y
				+ ", z="
				+ z
				+" }");
#endif
        	return session.SendPack(Pack_for_uploadPlayerPos(regionCid, x, y, z));
        }
		
		public static SendPackage Pack_for_uploadPlayerPos(int regionCid, float x, float y, float z) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_uploadPlayerPos;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(regionCid);
			_out.Write_float(x);
			_out.Write_float(y);
			_out.Write_float(z);
			return si_p;
		}
		/// <summary>
        /// 请求执行服务
        /// </summary>
    	public UniTask<RequestExeServiceResultData> CS_requestExeService(int npcId, int index)
        {
            return _CS_requestExeService(npcId, index);
        }
        
        public UniTask<RequestExeServiceResultData> _CS_requestExeService(int npcId, int index)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(RequestExeServiceResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mainCity_requestExeService, "Send->"+"MainCity.CS_requestExeService { "
				+ "npcId="
				+ npcId
				+ ", index="
				+ index
				+" }");
#endif
        	UniTask<RequestExeServiceResultData> task = MsgAsyncAwaiter<RequestExeServiceResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_requestExeService(npcId, index));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mainCity_requestExeServiceResult);
			return task;
        }
		
		public static SendPackage Pack_for_requestExeService(int npcId, int index) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_requestExeService;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(npcId);
			_out.Write_int(index);
			return si_p;
		}
#endregion
#region Messages
        public struct NotifyWeatherData : IReceiveMessage {
	        public int weatherCid;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                weatherCid = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mainCity_notifyWeather;}
            
            public override string ToString()
            {
                return "MainCity.notifyWeather"+ ", weatherCid="+ weatherCid;
            }
        }
        public struct RequestExeServiceResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public int regionCid;
	        public MainCityNpcPOD npcData;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                regionCid = _in.HasRemaining() ? _in.Read_int() : default;
                npcData = _in.HasRemaining() ? _in.Read_pod<MainCityNpcPOD>(MainCityNpcPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mainCity_requestExeServiceResult;}
            
            public override string ToString()
            {
                return "MainCity.requestExeServiceResult"+ ", code="+ code+ ", regionCid="+ regionCid+ ", npcData="+ npcData;
            }
        }
        public struct NotifyNpcUpdateData : IReceiveMessage {
	        public int regionCid;
	        public MainCityNpcPOD npcData;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                regionCid = _in.HasRemaining() ? _in.Read_int() : default;
                npcData = _in.HasRemaining() ? _in.Read_pod<MainCityNpcPOD>(MainCityNpcPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mainCity_notifyNpcUpdate;}
            
            public override string ToString()
            {
                return "MainCity.notifyNpcUpdate"+ ", regionCid="+ regionCid+ ", npcData="+ npcData;
            }
        }
        public struct NotifyNpcDropData : IReceiveMessage {
	        public int regionCid;
	        public int npcId;
	        public List<ItemShowPOD> awards;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                regionCid = _in.HasRemaining() ? _in.Read_int() : default;
                npcId = _in.HasRemaining() ? _in.Read_int() : default;
                awards = _in.HasRemaining() ? _in.Read_list_pod<ItemShowPOD>(ItemShowPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mainCity_notifyNpcDrop;}
            
            public override string ToString()
            {
                return "MainCity.notifyNpcDrop"+ ", regionCid="+ regionCid+ ", npcId="+ npcId+ ", awards="+ awards.ToString<ItemShowPOD>();
            }
        }
        public struct NotifyNpcExecutionData : IReceiveMessage {
	        public int regionCid;
	        public int npcId;
	        public int excutionId;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                regionCid = _in.HasRemaining() ? _in.Read_int() : default;
                npcId = _in.HasRemaining() ? _in.Read_int() : default;
                excutionId = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mainCity_notifyNpcExecution;}
            
            public override string ToString()
            {
                return "MainCity.notifyNpcExecution"+ ", regionCid="+ regionCid+ ", npcId="+ npcId+ ", excutionId="+ excutionId;
            }
        }
    }
#endregion
}